package com.vichat.room.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.vichat.common.cache.LocalCacher;
import com.vichat.common.cache.RedisHelper;
import com.vichat.common.constant.GlobalConstant;
import com.vichat.common.threads.RefreshDataThread;
import com.vichat.common.threads.SysMsgThread;
import com.vichat.common.util.NumberUtils;
import com.vichat.common.vo.PageFilter;
import com.vichat.common.vo.SysMsg;
import com.vichat.core.dao.BaseDaoI;
import com.vichat.room.entity.RoomBasic;
import com.vichat.room.entity.RoomBlacklist;
import com.vichat.room.entity.RoomMember;
import com.vichat.room.entity.TypedefWindowId;
import com.vichat.room.service.IRoomService;
import com.vichat.room.vo.RoomVO;
import com.vichat.user.entity.UserBasic;
import com.vichat.user.service.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.exception.LockAcquisitionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static org.slf4j.LoggerFactory.*;

/**
 * Created by ranjx on 2017/11/20.
 */
@Service("roomService")
public class RoomServiceImpl implements IRoomService {
    private static transient final Logger logger = getLogger(RoomServiceImpl.class);


    ExecutorService tp = Executors.newCachedThreadPool();
    @Autowired
    private BaseDaoI<RoomBasic> roomDao;
    @Autowired
    private BaseDaoI<RoomMember> roomMemberDao;
    @Autowired
    private IUserService userService;

    /**
     * 查询频道1
     *
     * @param queryBean
     * @param pf
     * @return
     */
    @SuppressWarnings("unchecked")
    @Override
    public List<RoomBasic> queryRoomBasics(RoomBasic queryBean, PageFilter pf) throws Exception {
        if (NumberUtils.isNotNullOrZero(queryBean.getUid())) {//按频道成员搜索
            String sql = "SELECT a.* FROM room_basic a,room_member b WHERE a.state=1 and b.state=1 and a.rid = b.rid and b.uid=:uid";
            HashMap params = new HashMap();
            params.put("uid", queryBean.getUid());

            List<RoomBasic> roomBasics = roomDao.findEntityBySql(sql + roomWhereSql(queryBean, params) + " order by rid desc ", params, RoomBasic.class, pf.getPage(), pf.getLimit());
            return roomBasics;
        } else {
            String hql = "from RoomBasic where state = 1";
            HashMap params = new HashMap();
            List<RoomBasic> roomBasics = roomDao.find(hql + roomWhereHql(queryBean, params) + " order by rid desc ", params, pf.getPage(), pf.getLimit());
            return roomBasics;
        }
    }

    /**
     * 查询频道数量
     *
     * @param queryBean
     * @return
     */
    public Long countRoomBasics(RoomBasic queryBean) throws Exception {
        if (NumberUtils.isNotNullOrZero(queryBean.getUid())) {//按频道成员搜索
            String sql = "SELECT count(*) FROM room_basic a,room_member b WHERE a.state=1 and b.state=1 and a.rid = b.rid and b.uid=:uid";
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("uid", queryBean.getUid());
            return Long.parseLong(roomDao.countBySql(sql + roomWhereSql(queryBean, params), params).toString());
        } else {
            String hql = "select count(*) from RoomBasic where state = 1";
            Map<String, Object> params = new HashMap<String, Object>();
            return roomDao.count(hql + roomWhereHql(queryBean, params), params);
        }
    }

    /**
     * 拼装用户条件
     *
     * @param bean
     * @param params
     * @return
     */
    private String roomWhereHql(RoomBasic bean, Map<String, Object> params) throws Exception {
        String hql = "";
        if (bean != null) {
            if (StringUtils.isNotBlank(bean.getName())) {
                hql += " and name like :name";
                params.put("name", "%" + URLDecoder.decode(bean.getName(), "UTF-8") + "%");
            }
            if (NumberUtils.isNotNullOrZero(bean.getStyle())) {
                hql += " and style = :style";
                params.put("style", bean.getStyle());
            }
            if (NumberUtils.isNotNullOrZero(bean.getPartyId())) {
                hql += " and partyId = :partyId";
                params.put("partyId", bean.getPartyId());
            }
            if (StringUtils.isNotBlank(bean.getOrgCode())) {
                hql += " and orgCode like :orgCode";
                params.put("orgCode", bean.getOrgCode() + "%");
            }

        }
        return hql;
    }

    /**
     * 拼装用户条件（频道成员搜索）
     *
     * @param bean
     * @param params
     * @return
     */
    private String roomWhereSql(RoomBasic bean, Map<String, Object> params) throws Exception {
        String sql = "";
        if (bean != null) {
            if (NumberUtils.isNotNullOrZero(bean.getUid())) {
                // 按频道成员搜索
                sql += " and b.uid=:uid";
                params.put("uid", bean.getUid());
            }
            if (NumberUtils.isNotNullOrZero(bean.getState())) {
                sql += " and a.state = :state";
                params.put("state", bean.getState());
            }
            if (StringUtils.isNotBlank(bean.getName())) {
                sql += " and a.name like :name";
                params.put("name", "%" + URLDecoder.decode(bean.getName(), "UTF-8") + "%");
            }
            if (NumberUtils.isNotNullOrZero(bean.getStyle())) {
                sql += " and a.style = :style";
                params.put("style", bean.getStyle());
            }
            if (NumberUtils.isNotNullOrZero(bean.getPartyId())) {
                sql += " and a.party_id = :partyId";
                params.put("partyId", bean.getPartyId());
            }
            if (StringUtils.isNotBlank(bean.getOrgCode())) {
                sql += " and a.org_code like :orgCode";
                params.put("orgCode", bean.getOrgCode() + "%");
            }
        }
        return sql;
    }

    /**
     * 拼装排序字段
     *
     * @param pf
     * @return
     */
    private String orderHql(PageFilter pf) {
        String orderString = "";
        if (pf != null) {
            if ((pf.getSort() != null) && (pf.getOrder() != null)) {
                orderString = " order by " + pf.getSort() + " " + pf.getOrder();
            }
        }
        return orderString;
    }


    /**
     * 获取频道
     *
     * @param rid
     * @return
     */
    public RoomBasic getRoomBasicByRid(long rid) {
        String jsonStr = RedisHelper.getRoom(rid);
        RoomBasic roomBasic = null;
        if (StringUtils.isNotBlank(jsonStr)) {
            roomBasic = JSONObject.parseObject(jsonStr, RoomBasic.class);
        } else {
            roomBasic = roomDao.get("from RoomBasic where state = 1 and rid = " + rid);
            if(roomBasic != null) {
                RedisHelper.setRoom(roomBasic.getRid(), JSONObject.toJSONString(roomBasic));
            }
        }
        return roomBasic;
    }

    /**
     * 创建/修改频道
     *
     * @param room
     */
    @Override
    public RoomBasic saveRoomBasic(RoomBasic room) throws Exception {
        if (NumberUtils.isNullOrZero(room.getRid())) {
            room.setPttCtrl(2L);
            roomDao.save(room);
            this.updateRoomBasicVersion(room.getRid());
            RedisHelper.setRoom(room.getRid(), JSONObject.toJSONString(room));
        } else {
            RoomBasic roomBasicFDB = roomDao.get(RoomBasic.class, room.getRid());
            roomBasicFDB.setStyle(room.getStyle());
//            roomBasicFDB.setPttCtrl(room.getPttCtrl());
            roomBasicFDB.setName(room.getName());

            roomBasicFDB.setWin1(room.getWin1());//无视频|16k语音|自动麦
            roomBasicFDB.setWin2(room.getWin2());//视频窗口640x480码率300k|音频16khz|自动麦
            roomBasicFDB.setWin3(room.getWin3());//视频窗口640x480码率300k|音频16khz|自动麦
            roomBasicFDB.setWin4(room.getWin4());//视频窗口640x480码率300k|音频16khz|自动麦
            roomBasicFDB.setWin5(room.getWin5());//视频窗口640x480码率300k|音频16khz|自动麦
            roomBasicFDB.setWin6(room.getWin6());//视频窗口640x480码率300k|音频16khz|自动麦
            roomBasicFDB.setWin7(room.getWin7());//视频窗口640x480码率300k|音频16khz|自动麦
            roomBasicFDB.setWin8(room.getWin8());//视频窗口640x480码率300k|音频16khz|自动麦
            roomBasicFDB.setWin9(room.getWin9());//视频窗口640x480码率300k|音频16khz|自动麦
            roomBasicFDB.setWin10(room.getWin10());//视频窗口640x480码率300k|音频16khz|自动麦
            roomBasicFDB.setWin11(room.getWin11());//视频窗口640x480码率300k|音频16khz|自动麦
            roomBasicFDB.setWin12(room.getWin12());//视频窗口640x480码率300k|音频16khz|自动麦

            roomDao.update(roomBasicFDB);
            this.updateRoomBasicVersion(roomBasicFDB.getRid());
            //将频道放到redis
            RedisHelper.setRoom(roomBasicFDB.getRid(), JSONObject.toJSONString(roomBasicFDB));
        }
        return room;
    }

    /**
     * 创建/修改频道窗口
     *
     * @param room
     */
    public RoomBasic saveRoomWin(RoomBasic room) throws Exception {
        RoomBasic roomBasicFDB = roomDao.get(RoomBasic.class, room.getRid());
        roomBasicFDB.setWin1(room.getWin1());
        roomBasicFDB.setWin2(room.getWin2());
        roomBasicFDB.setWin3(room.getWin3());
        roomBasicFDB.setWin4(room.getWin4());
        roomBasicFDB.setWin5(room.getWin5());
        roomBasicFDB.setWin6(room.getWin6());
        roomBasicFDB.setWin7(room.getWin7());
        roomBasicFDB.setWin8(room.getWin8());
        roomBasicFDB.setWin9(room.getWin9());
        roomBasicFDB.setWin10(room.getWin10());
        roomBasicFDB.setWin11(room.getWin11());
        roomBasicFDB.setWin12(room.getWin12());
        roomDao.update(roomBasicFDB);
        this.updateRoomBasicVersion(roomBasicFDB.getRid());
        //将频道放到redis
        RedisHelper.setRoom(roomBasicFDB.getRid(), JSONObject.toJSONString(roomBasicFDB));
        return roomBasicFDB;
    }

    /**
     * 删除频道
     *
     * @param rid
     */
    public RoomBasic delRoomBasic(long rid) throws Exception {
        RoomBasic roomBasicFDB = this.getRoomBasicByRid(rid);
        if (roomBasicFDB != null) {
            roomDao.delete(roomBasicFDB);
            RedisHelper.delRoom(rid);
        }
        this.delRoomMemberLogically(rid, 0l);
        return roomBasicFDB;
    }

    /**
     * 删除频道
     *
     * @param roomBasicFDB
     */
    public RoomBasic delRoomBasic(RoomBasic roomBasicFDB) throws Exception {
        if (roomBasicFDB != null) {
            roomDao.delete(roomBasicFDB);
            RedisHelper.delRoom(roomBasicFDB.getRid());
        }
        this.delRoomMemberLogically(roomBasicFDB.getRid(), 0l);
        return roomBasicFDB;
    }

    /**
     * 查询频道成员
     *
     * @param queryBean
     * @param pf
     * @return
     */
    public List<RoomMember> queryRoomMemers(RoomMember queryBean, PageFilter pf) throws Exception {
        String hql = "from RoomMember where state=1 ";
        HashMap params = new HashMap();
        List<RoomMember> roomMembers = roomMemberDao.find(hql + roomMemberWhereHql(queryBean, params) + PageFilter.orderHql(pf), params, pf.getPage(), pf.getLimit());
        return roomMembers;
    }

    /*
     * 查询频道成员
     *
     * @param queryBean
     * @param pf
     * @return
     */
    public List<RoomMember> queryAllRoomMembers(RoomMember queryBean) throws Exception {
        String hql = "from RoomMember where rid = :rid ";
        HashMap params = new HashMap();
        params.put("rid", queryBean.getRid());
        List<RoomMember> roomMembers = roomMemberDao.find(hql, params);
        return roomMembers;
    }

    /**
     * 查询删除成员的所在频道
     *
     * @param uids
     * @return
     */
    @Override
    public List<RoomBasic> queryDelUserRoomBasics(String uids) throws Exception {
        String sql = "select DISTINCT a.* from roomdb.room_basic a,roomdb.room_member b where a.rid = b.rid and  uid in( " + uids + ") and admin_grade = 0 and a.state=0";
        List<RoomBasic> roomBasics = roomDao.findEntityBySql(sql, null, RoomBasic.class);
        return roomBasics;
    }

    /**
     * 获取频道成员
     *
     * @param rid
     * @return
     */
    public RoomMember getRoomMember(long rid, long uid) {
        String hql = "from RoomMember where state=1 and rid=:rid and uid=:uid";
        HashMap params = new HashMap();
        params.put("rid", rid);
        params.put("uid", uid);
        List<RoomMember> roomMembers = roomMemberDao.find(hql, params);
        if (!roomMembers.isEmpty()) {
            return roomMembers.get(0);
        }
        return null;
    }

    /**
     * 查询频道成员数量
     *
     * @param queryBean
     * @return
     */
    public Long countRoomMembers(RoomMember queryBean) throws Exception {
        String hql = "select count(*) from RoomMember where state=1 ";
        Map<String, Object> params = new HashMap<String, Object>();
        return roomMemberDao.count(hql + roomMemberWhereHql(queryBean, params), params);
    }

    /**
     * 拼装用户条件
     *
     * @param bean
     * @param params
     * @return
     */
    private String roomMemberWhereHql(RoomMember bean, Map<String, Object> params) throws Exception {
        String hql = "";
        if (bean != null) {
            if (NumberUtils.isNotNullOrZero(bean.getRid())) {
                hql += " and rid = :rid";
                params.put("rid", bean.getRid());
            }
            if (NumberUtils.isNotNullOrZero(bean.getUid())) {
                hql += " and uid = :uid";
                params.put("uid", bean.getUid());
            }
            if (StringUtils.isNotBlank(bean.getUserName())) {
                hql += " and userName like :userName";
                params.put("userName", "%" + URLDecoder.decode(bean.getUserName(), "UTF-8") + "%");
            }
        }
        return hql;
    }

    /**
     * 新增修改频道成员
     *
     * @param member
     */
    public void saveRoomMember(RoomMember member) throws Exception {
        RoomBasic roomBasicFDB = this.getRoomBasicByRid(member.getRid());
        if (NumberUtils.isNotNullOrZero(roomBasicFDB.getOwnerId()) && roomBasicFDB.getOwnerId().longValue() == member.getUid()) {
            member.setAdminGrade(GlobalConstant.ROOM_RIGHT_10);
            member.setPriority(GlobalConstant.ROOM_RIGHT_10);//群主优先级最高
        }
        RoomMember memberFDB = this.getRoomMember(member.getRid(), member.getUid());
        if (memberFDB != null) {
            StringBuilder sql = new StringBuilder();
            sql.append("update roomdb.room_member set admin_grade=").append(member.getAdminGrade());
            sql.append(",priority=").append(member.getPriority());
            sql.append(",timelen=").append(member.getTimelen());
            sql.append(",videolen=").append(member.getVideolen());
            sql.append(" ,version = REPLACE(unix_timestamp(current_timestamp(3)),'.','') ");
            sql.append(" where rid=").append(member.getRid());
            sql.append(" and uid=").append(member.getUid());
            roomMemberDao.executeSql(sql.toString());
        } else {
            StringBuilder sql = new StringBuilder();
            sql.append("insert into roomdb.room_member(rid,uid,admin_grade,user_name,priority,timelen,videolen,state,version) values (:rid,:uid,:adminGrade,:userName,:priority,:timelen,:videolen,:state,unix_timestamp(current_timestamp())) ");
            sql.append("ON DUPLICATE KEY UPDATE state = 1,admin_grade=:adminGrade,user_name=:userName,priority=:priority,timelen=:timelen,videolen=:videolen,version=unix_timestamp(current_timestamp())");
            HashMap params = new HashMap();
            params.put("rid", member.getRid());
            params.put("uid", member.getUid());
            params.put("adminGrade", member.getAdminGrade());
            params.put("userName", member.getUserName());
            params.put("priority", member.getPriority());
            params.put("timelen", member.getTimelen());
            params.put("videolen", member.getVideolen());
            params.put("state", 1L);
            roomMemberDao.executeSql(sql.toString(), params);
        }
    }

    /**
     * 彻底删除频道成员
     *
     * @param rid
     */
    public void delUselessMembers(long rid) throws Exception {
        StringBuilder sql = new StringBuilder();
        sql.append("delete from roomdb.room_member where rid=").append(rid);
        sql.append(" and admin_grade = 0 and state=0");
        roomMemberDao.executeSql(sql.toString());
        RoomBasic roomBasicFDB = this.getRoomBasicByRid(rid);
        //更新一下version
        if (roomBasicFDB != null) {
            roomDao.saveOrUpdate(roomBasicFDB);
            this.updateRoomBasicVersion(roomBasicFDB.getRid());
            RedisHelper.setRoom(rid, JSONObject.toJSONString(roomBasicFDB));
        }
    }

    /**
     * 彻底删除频道成员
     *
     * @param uid
     */
    public void delUselessMembersByUid(long uid) throws Exception {
        StringBuilder sql = new StringBuilder();
        sql.append("delete from roomdb.room_member where uid=").append(uid);
        sql.append(" and admin_grade = 0 and state=0");
        roomMemberDao.executeSql(sql.toString());
//        RoomBasic roomBasicFDB = this.getRoomBasicByUid(rid);
//        //更新一下version
//        if (roomBasicFDB != null) {
//            roomDao.saveOrUpdate(roomBasicFDB);
//            RedisHelper.setRoom(uid, JSONObject.toJSONString(roomBasicFDB));
//        }
    }

    /**
     * 删除频道成员
     *
     * @param rid
     */
    public void delRoomMembers(long rid) throws Exception {
        StringBuilder sql = new StringBuilder();
        sql.append("delete from roomdb.room_member where rid=").append(rid);
        roomMemberDao.executeSql(sql.toString());
        RoomBasic roomBasicFDB = this.getRoomBasicByRid(rid);
        //更新一下version
        if (roomBasicFDB != null) {
            roomDao.saveOrUpdate(roomBasicFDB);
            this.updateRoomBasicVersion(roomBasicFDB.getRid());
            RedisHelper.setRoom(rid, JSONObject.toJSONString(roomBasicFDB));
        }
    }


    /**
     * 修改频道成员的权限为0，逻辑删除
     *
     * @param rid
     * @param uid
     * @throws Exception
     */
    public void delRoomMemberLogically(long rid, long uid) throws Exception {
        StringBuilder sql = new StringBuilder();
        if (NumberUtils.isNotNullOrZero(rid)) {
            sql.append("update roomdb.room_member set admin_grade = 0 ,state = 0 ,version = REPLACE(unix_timestamp(current_timestamp(3)),'.','') where rid = ").append(rid);
        }
        if (NumberUtils.isNotNullOrZero(uid)) {
            sql.append(" and uid = ").append(uid);
        }
        roomMemberDao.executeSql(sql.toString());
    }

    /**
     * 修改频道成员的权限为0，逻辑删除
     *
     * @param uid
     * @throws Exception
     */
    public void delRoomMemberLogicallyByUid(long uid) throws Exception {
        StringBuilder sql = new StringBuilder();
        if (NumberUtils.isNotNullOrZero(uid)) {
            sql.append("update roomdb.room_member set admin_grade = 0 ,state = 0 ,version = REPLACE(unix_timestamp(current_timestamp(3)),'.','') where ");
            sql.append(" uid = ").append(uid);
            roomMemberDao.executeSql(sql.toString());
        }
    }

    /**
     * 删除频道成员
     *
     * @param rid
     * @param uid
     * @throws Exception
     */
    public void delRoomMember(long rid, long uid) throws Exception {
        StringBuilder sql = new StringBuilder();
        sql.append("delete from roomdb.room_member where rid=").append(rid);
        sql.append(" and uid=").append(uid);
        roomMemberDao.executeSql(sql.toString());
    }

    /**
     * 检查频道成员
     *
     * @param rid
     * @param uid
     * @return
     * @throws Exception
     */
    public boolean checkRoomMember(long rid, long uid) throws Exception {
        HashMap params = new HashMap();
        String hql = "from RoomMember where rid = :rid and uid = :uid and state=1";
        params.put("rid", rid);
        params.put("uid", uid);
        List<RoomMember> roomMembers = roomMemberDao.find(hql, params);
        if (!roomMembers.isEmpty()) {
            return true;
        }
        return false;
    }

    /**
     * 获取频道列表
     *
     * @param bean
     * @param pf
     * @return
     * @throws Exception
     */
    public List<RoomBasic> queryRoomBasicsList(RoomBasic bean, PageFilter pf) throws Exception {
        List<RoomBasic> roomList = new ArrayList<>();
        String hql = "from RoomBasic where 1 = 1";
        HashMap params = new HashMap();
        if (NumberUtils.isNotNull(bean.getVersion())) {
            hql += " and version > :version";
            params.put("version", bean.getVersion());
        }
        if (NumberUtils.isNotNullOrZero(bean.getPartyId())) {
            hql += " and partyId = :partyId";
            params.put("partyId", bean.getPartyId());
        }
        List<RoomBasic> roomBasics = roomDao.find(hql + orderHql(pf), params, pf.getPage(), pf.getLimit());
        if (!roomBasics.isEmpty()) {
            for (RoomBasic room : roomBasics) {
                //视频会议 视频监控
                if (room.getStyle().longValue() == GlobalConstant.ROOM_STYLE_4 || room.getStyle().longValue() == GlobalConstant.ROOM_STYLE_5) {
                    roomList.add(room);
                } else {
                    if (checkRoomMember(room.getRid(), bean.getOwnerId())) {
                        roomList.add(room);
                    }
                }
            }
        }
        return roomList;
    }

    /**
     * 获取视频窗口列表
     *
     * @param rid
     * @return
     * @throws Exception
     */
    public List<TypedefWindowId> queryTypedefWindowIds(long rid) throws Exception {
        List<TypedefWindowId> windowIds = new ArrayList<>();
        RoomBasic roomBasicFDB = this.getRoomBasicByRid(rid);
        TypedefWindowId typedefWindowId = null;
        if (NumberUtils.isNotNullOrZero(roomBasicFDB.getWin1())) {
            typedefWindowId = LocalCacher.get("TYPEDEF_WINDOW_ID", "Type_WindowId", roomBasicFDB.getWin1().toString(), TypedefWindowId.class);
            typedefWindowId.setWinNum(1);
            windowIds.add(typedefWindowId);
        }
        if (NumberUtils.isNotNullOrZero(roomBasicFDB.getWin2())) {
            typedefWindowId = LocalCacher.get("TYPEDEF_WINDOW_ID", "Type_WindowId", roomBasicFDB.getWin2().toString(), TypedefWindowId.class);
            typedefWindowId.setWinNum(2);
            windowIds.add(typedefWindowId);
        }
        if (NumberUtils.isNotNullOrZero(roomBasicFDB.getWin3())) {
            typedefWindowId = LocalCacher.get("TYPEDEF_WINDOW_ID", "Type_WindowId", roomBasicFDB.getWin3().toString(), TypedefWindowId.class);
            typedefWindowId.setWinNum(3);
            windowIds.add(typedefWindowId);
        }
        if (NumberUtils.isNotNullOrZero(roomBasicFDB.getWin4())) {
            typedefWindowId = LocalCacher.get("TYPEDEF_WINDOW_ID", "Type_WindowId", roomBasicFDB.getWin4().toString(), TypedefWindowId.class);
            typedefWindowId.setWinNum(4);
            windowIds.add(typedefWindowId);
        }
        if (NumberUtils.isNotNullOrZero(roomBasicFDB.getWin5())) {
            typedefWindowId = LocalCacher.get("TYPEDEF_WINDOW_ID", "Type_WindowId", roomBasicFDB.getWin5().toString(), TypedefWindowId.class);
            typedefWindowId.setWinNum(5);
            windowIds.add(typedefWindowId);
        }
        if (NumberUtils.isNotNullOrZero(roomBasicFDB.getWin6())) {
            typedefWindowId = LocalCacher.get("TYPEDEF_WINDOW_ID", "Type_WindowId", roomBasicFDB.getWin6().toString(), TypedefWindowId.class);
            typedefWindowId.setWinNum(6);
            windowIds.add(typedefWindowId);
        }
        if (NumberUtils.isNotNullOrZero(roomBasicFDB.getWin7())) {
            typedefWindowId = LocalCacher.get("TYPEDEF_WINDOW_ID", "Type_WindowId", roomBasicFDB.getWin7().toString(), TypedefWindowId.class);
            typedefWindowId.setWinNum(7);
            windowIds.add(typedefWindowId);
        }
        if (NumberUtils.isNotNullOrZero(roomBasicFDB.getWin8())) {
            typedefWindowId = LocalCacher.get("TYPEDEF_WINDOW_ID", "Type_WindowId", roomBasicFDB.getWin8().toString(), TypedefWindowId.class);
            typedefWindowId.setWinNum(8);
            windowIds.add(typedefWindowId);
        }
        if (NumberUtils.isNotNullOrZero(roomBasicFDB.getWin9())) {
            typedefWindowId = LocalCacher.get("TYPEDEF_WINDOW_ID", "Type_WindowId", roomBasicFDB.getWin9().toString(), TypedefWindowId.class);
            typedefWindowId.setWinNum(9);
            windowIds.add(typedefWindowId);
        }
        if (NumberUtils.isNotNullOrZero(roomBasicFDB.getWin10())) {
            typedefWindowId = LocalCacher.get("TYPEDEF_WINDOW_ID", "Type_WindowId", roomBasicFDB.getWin10().toString(), TypedefWindowId.class);
            typedefWindowId.setWinNum(10);
            windowIds.add(typedefWindowId);
        }
        if (NumberUtils.isNotNullOrZero(roomBasicFDB.getWin11())) {
            typedefWindowId = LocalCacher.get("TYPEDEF_WINDOW_ID", "Type_WindowId", roomBasicFDB.getWin11().toString(), TypedefWindowId.class);
            typedefWindowId.setWinNum(11);
            windowIds.add(typedefWindowId);
        }
        if (NumberUtils.isNotNullOrZero(roomBasicFDB.getWin12())) {
            typedefWindowId = LocalCacher.get("TYPEDEF_WINDOW_ID", "Type_WindowId", roomBasicFDB.getWin12().toString(), TypedefWindowId.class);
            typedefWindowId.setWinNum(12);
            windowIds.add(typedefWindowId);
        }
        return windowIds;
    }

    /**
     * 发送ROOM消息
     *
     * @param sysMsgs
     */
    public void sendSysMsg(List<SysMsg> sysMsgs) throws Exception {
        tp.execute(new SysMsgThread(sysMsgs));
    }

    /**
     * 创建频道和频道成员
     *
     * @param roomVO
     * @throws Exception
     */
    public RoomBasic createRoom2Member(RoomVO roomVO) throws Exception {
        RoomBasic defRoom = new RoomBasic();
        defRoom.setStyle(roomVO.getStyle());
        defRoom.setName(roomVO.getName());
        defRoom.setCapacity(1000l);
        defRoom.setExpireType(roomVO.getExpireType());
        defRoom.setLoginType(1l);
        defRoom.setEnterCtrl(1l);
        defRoom.setOfflineCtrl(1l);
        defRoom.setPttCtrl(2l);//优先级对讲，高级可抢夺
        defRoom.setOwnerId(roomVO.getUid());
        defRoom.setPartyId(roomVO.getPartyId());
        defRoom.setOrgId(roomVO.getOrgId());
        defRoom.setOrgCode(roomVO.getOrgCode());
        if (roomVO.getStyle() == 1l) {//语音
            defRoom.setWin1(100l);
        } else {
            defRoom.setWin1(100l);
            defRoom.setWin2(15l);
            defRoom.setWin3(15l);
            defRoom.setWin4(15l);
            defRoom.setWin5(15l);
        }
        defRoom.setHour(roomVO.getHour());
        RoomBasic roomBasicFDB = this.saveRoomBasic(defRoom);
        if (!roomVO.getUids().isEmpty() && roomBasicFDB != null) {
            for (long uid : roomVO.getUids()) {
                RoomMember member = new RoomMember();
                member.setRid(roomBasicFDB.getRid());
                member.setUid(uid);
                member.setAdminGrade(5l);
                //5 成员 15 群主
                if (uid == roomVO.getUid()) {
                    member.setPriority(3l);
                } else {
                    member.setPriority(2l);
                }
                member.setTimelen(30l);
                member.setUserName(getNameByUid(uid));
                member.setVideolen(0L);
                this.saveRoomMember(member);
            }
        }
        return roomBasicFDB;
    }

    /**
     * 获取用户名称
     *
     * @param uid
     * @return
     */
    private String getNameByUid(long uid) {
        String jsonStr = RedisHelper.getUser(uid);
        JSONObject obj = JSONObject.parseObject(jsonStr);
        if (obj != null && obj.containsKey("userName")) {
            return obj.getString("userName");
        }
        return "";
    }

    /**
     * 根据频道名称模糊查询频道成员
     *
     * @param userName
     * @return
     * @throws Exception
     */
    public List<RoomMember> getRoomMembersByUserName(String userName) throws Exception {
        StringBuilder sql = new StringBuilder();
        sql.append("select * from  roomdb.room_member where state=1 and rid in (select rid from room_basic where name like '%" + userName + "%') order by  uid");
        Map<String, Object> params = new HashMap<String, Object>();
        List<RoomMember> roomMembers = roomMemberDao.findEntityBySql(sql.toString(), params, RoomMember.class);
        return roomMembers;
    }

    /**
     * 获取临时过期频道
     *
     * @return
     * @throws Exception
     */
    public List<RoomBasic> queryExpireRoom() throws Exception {
        StringBuilder sql = new StringBuilder();
        sql.append("select * from roomdb.room_basic where state=1 and expire_type=0 and TIMESTAMPDIFF(hour,create_time,NOW()) > hour ORDER BY hour desc");
        Map<String, Object> params = new HashMap<String, Object>();
        List<RoomBasic> roomBasics = roomDao.findEntityBySql(sql.toString(), params, RoomBasic.class);
        return roomBasics;
    }

    @Override
    public void updateUserName(long uid, String userName) {
        List<RoomMember> roomMemberList = getRoomMemberByUid(uid);
        if (roomMemberList != null && roomMemberList.size() > 0) {
            String hql = "update roomdb.room_member set user_name = '"+ userName +"' , version = REPLACE(unix_timestamp(current_timestamp(3)),'.','') where uid = "+ uid +" and admin_grade != 0 and state=1";
            roomMemberDao.executeSql(hql);

            for (RoomMember roomMember : roomMemberList) {
                //刷新房间信息
                logger.info("刷新频道" + roomMember.getRid());
                refreshRoom(String.valueOf(roomMember.getRid()));
            }
        }
    }

    /**
     * 删除频道成员
     *
     * @param uid
     */
    public void deleteRoomMemberByUid(long uid) throws Exception {
        RoomMember queryBean = new RoomMember();
        PageFilter pf = new PageFilter();
        queryBean.setUid(uid);
        List<RoomMember> roomMembers = this.queryRoomMemers(queryBean, pf);
        if (roomMembers.size() > 0) {
            for (RoomMember roomMember : roomMembers) {
                roomMemberDao.delete(roomMember);
                this.delRoomMember(roomMember.getRid(), roomMember.getUid());
                RoomBasic roomBasicFDB = this.getRoomBasicByRid(roomMember.getRid());
                //更新一下version
                if (roomBasicFDB != null) {
                    roomDao.saveOrUpdate(roomBasicFDB);
                    this.updateRoomBasicVersion(roomBasicFDB.getRid());
                }
            }
        }
    }

    /**
     * 刷新房间信息
     *
     * @param rids
     * @return
     */
    public int refreshRoom(String... rids) {
        tp.execute(new RefreshDataThread("rid", rids, "refresh_data"));
        return 1;
    }

    /**
     * 获取频道用户
     *
     * @param uid
     * @return
     */
    public List<RoomMember> getRoomMemberByUid(long uid) {
        String hql = "from RoomMember where uid = :uid and adminGrade != 0 and state=1";
        HashMap params = new HashMap();
        params.put("uid", uid);
        List<RoomMember> list = roomMemberDao.find(hql, params);
        return list;
    }


    public List<RoomMember> queryRoomMembersByRId(long rid) {
        String hql = "from RoomMember where adminGrade != 0 and rid = :rid and state=1";
        HashMap params = new HashMap();
        params.put("rid", rid);
        List<RoomMember> channelUserList = roomMemberDao.find(hql, params);

        return channelUserList;
    }

    /**
     * 创建/修改频道
     *
     * @param roomBasic
     */
    public RoomBasic createPersonRoomBasic(RoomBasic roomBasic, long[] uids) {
        if (NumberUtils.isNullOrZero(roomBasic.getRid())) {
            roomDao.save(roomBasic);
            this.updateRoomBasicVersion(roomBasic.getRid());
            RedisHelper.setRoom(roomBasic.getRid(), JSONObject.toJSONString(roomBasic));

            boolean isFindCreateUid = false;
            List<String> channelUserUids = new ArrayList<>();
            for (long uid : uids) {
                String uname = RedisHelper.getUname(uid);
                if (StringUtils.isNotBlank(uname)) {
                    UserBasic userBasic = userService.getUserBasicByUid(uid);
                    if(userBasic != null) {
                        if (uid == roomBasic.getOwnerId()) {
                            isFindCreateUid = true;
                        }
                        if (!GlobalConstant.SUPPORT_ADMIN_LOGIN_APP && userBasic.getUserType() == GlobalConstant.USER_TYPE_2) {
                            continue;
                        }
                        channelUserUids.add(String.valueOf(uid));
                        addRoomMember(roomBasic.getRid(), uid, uname, false);
                    }
                }
            }
            if (!isFindCreateUid && roomBasic.getOwnerId() != 0) {//如果未找到创建者uid，那么补加下
                channelUserUids.add(String.valueOf(roomBasic.getOwnerId()));
                addRoomMember(roomBasic.getRid(), roomBasic.getOwnerId(), RedisHelper.getUname(roomBasic.getOwnerId()), false);
            }
            try {
                //刷新频道信息
                refreshRoom(roomBasic.getRid());
                //刷新房间信息
                refreshRoom(String.valueOf(roomBasic.getRid()));
            } catch (Exception ex) {
                logger.error("频道添加redis/刷新房间信息异常");
            }

        }
        return roomBasic;
    }

    public void addRoomMember(long rid, Long uid, String uname, boolean refreshRoom) {
        RoomMember roomMember = new RoomMember();
        roomMember.setRid(rid);
        roomMember.setUid(uid);
        roomMember.setAdminGrade(5L);
        roomMember.setUserName(uname);
        roomMember.setTimelen(30L);
        roomMember.setPriority(2L);
        roomMemberDao.save(roomMember);

    }

    /**
     * 刷新频道信息
     *
     * @param rid
     * @return
     */
    public int refreshRoom(Long rid) {
        SysMsg sysMsg = new SysMsg();
        sysMsg.setCmdType(GlobalConstant.GMS_EVENT_QUEUE);
        sysMsg.setMsgType(GlobalConstant.MSG_TYPE_ADDCHANNEL);
        sysMsg.setSndId(10000);
        sysMsg.setRid(rid);
        List<SysMsg> sysMsgList = new ArrayList<SysMsg>();
        sysMsgList.add(sysMsg);
        tp.execute(new SysMsgThread(sysMsgList));
        return 1;
    }

    public void setRoomMemberAdminGrade(Long uid, Long rid, Long adminGrade) {
        StringBuffer sql = new StringBuffer();
        if (NumberUtils.isNotNullOrZero(uid) && NumberUtils.isNotNullOrZero(rid)) {
            sql.append("update roomdb.room_member set admin_grade = ").append(adminGrade).append(" where rid = ").append(rid);
            sql.append(" and uid = ").append(uid);
            roomMemberDao.executeSql(sql.toString());
            this.updateRoomMemberVersion(uid, rid);
        }
    }

    public void setSwitchRecord(RoomBasic roomBasic) {
        StringBuffer sql = new StringBuffer();
        if (NumberUtils.isNotNullOrZero(roomBasic.getRid())) {
            sql.append("update roomdb.room_basic set record = ").append(roomBasic.getRecord());
            sql.append(" where rid = ").append(roomBasic.getRid());
            roomDao.executeSql(sql.toString());
            this.updateRoomBasicVersion(roomBasic.getRid());
        }
    }

    public void updateRoomExpiredType(Long rid, Long expiredType, Long hour) {
        StringBuffer sql = new StringBuffer();
        if (NumberUtils.isNotNullOrZero(rid)) {
            sql.append("update roomdb.room_basic set expired_type = ").append(expiredType).append(" hour = ").append(hour);
            sql.append(" where rid = ").append(rid);
            roomDao.executeSql(sql.toString());
            this.updateRoomBasicVersion(rid);
        }
    }

    public void updateRoomBasicVersion(long rid) {
        String hql = "update roomdb.room_basic set version = REPLACE(unix_timestamp(current_timestamp(3)),'.','') where rid=" + rid;
        roomDao.executeSql(hql);
    }

    public void updateRoomMemberVersion(long uid, long rid) {
        String hql = "update roomdb.room_member set version = REPLACE(unix_timestamp(current_timestamp(3)),'.','') where rid=" + rid;
        if (NumberUtils.isNotNullOrZero(uid)) {
            hql += " and uid=" + uid;
        }
        roomMemberDao.executeSql(hql);
    }

    public void updateRoomBasicRecordByPartyId(long partyId,long record) {
        String hql = "update roomdb.room_basic set record=" + record +" ,version = REPLACE(unix_timestamp(current_timestamp(3)),'.','') where party_id=" + partyId;
        roomDao.executeSql(hql);
    }
}
